{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Sebastian Raschka](http://sebastianraschka.com), 2015\n",
    "\n",
    "https://github.com/rasbt/python-machine-learning-book"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python Machine Learning Essentials - Code Examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Bonus Material - A Simple Logistic Regression Implementation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the optional watermark extension is a small IPython notebook plugin that I developed to make the code reproducible. You can just skip the following line(s)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Sebastian Raschka \n",
      "Last updated: 12/22/2015 \n",
      "\n",
      "CPython 3.5.1\n",
      "IPython 4.0.1\n",
      "\n",
      "numpy 1.10.2\n",
      "pandas 0.17.1\n",
      "matplotlib 1.5.0\n"
     ]
    }
   ],
   "source": [
    "%load_ext watermark\n",
    "%watermark -a 'Sebastian Raschka' -u -d -v -p numpy,pandas,matplotlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# to install watermark just uncomment the following line:\n",
    "#%install_ext https://raw.githubusercontent.com/rasbt/watermark/master/watermark.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Overview"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Please see Chapter 3 for more details on logistic regression.\n",
    "\n",
    "![](./images/logistic_regression_schematic.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Implementing logistic regression in Python"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following implementation is similar to the Adaline implementation in [Chapter 2](../ch02/ch02.ipynb) except that we replace the sum of squared errors cost function with the logistic cost function\n",
    "\n",
    "$$J(\\mathbf{w}) = \\sum_{i=1}^{m} - y^{(i)} log \\bigg( \\phi\\big(z^{(i)}\\big) \\bigg) - \\big(1 - y^{(i)}\\big) log\\bigg(1-\\phi\\big(z^{(i)}\\big)\\bigg).$$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "class LogisticRegression(object):\n",
    "    \"\"\"LogisticRegression classifier.\n",
    "\n",
    "    Parameters\n",
    "    ------------\n",
    "    eta : float\n",
    "        Learning rate (between 0.0 and 1.0)\n",
    "    n_iter : int\n",
    "        Passes over the training dataset.\n",
    "\n",
    "    Attributes\n",
    "    -----------\n",
    "    w_ : 1d-array\n",
    "        Weights after fitting.\n",
    "    cost_ : list\n",
    "        Cost in every epoch.\n",
    "\n",
    "    \"\"\"\n",
    "    def __init__(self, eta=0.01, n_iter=50):\n",
    "        self.eta = eta\n",
    "        self.n_iter = n_iter\n",
    "\n",
    "    def fit(self, X, y):\n",
    "        \"\"\" Fit training data.\n",
    "\n",
    "        Parameters\n",
    "        ----------\n",
    "        X : {array-like}, shape = [n_samples, n_features]\n",
    "            Training vectors, where n_samples is the number of samples and\n",
    "            n_features is the number of features.\n",
    "        y : array-like, shape = [n_samples]\n",
    "            Target values.\n",
    "\n",
    "        Returns\n",
    "        -------\n",
    "        self : object\n",
    "\n",
    "        \"\"\"\n",
    "        self.w_ = np.zeros(1 + X.shape[1])\n",
    "        self.cost_ = []       \n",
    "        for i in range(self.n_iter):\n",
    "            y_val = self.activation(X)\n",
    "            errors = (y - y_val)\n",
    "            neg_grad = X.T.dot(errors)\n",
    "            self.w_[1:] += self.eta * neg_grad\n",
    "            self.w_[0] += self.eta * errors.sum()\n",
    "            self.cost_.append(self._logit_cost(y, self.activation(X)))\n",
    "        return self\n",
    "\n",
    "    def _logit_cost(self, y, y_val):\n",
    "        logit = -y.dot(np.log(y_val)) - ((1 - y).dot(np.log(1 - y_val)))\n",
    "        return logit\n",
    "    \n",
    "    def _sigmoid(self, z):\n",
    "        return 1.0 / (1.0 + np.exp(-z))\n",
    "    \n",
    "    def net_input(self, X):\n",
    "        \"\"\"Calculate net input\"\"\"\n",
    "        return np.dot(X, self.w_[1:]) + self.w_[0]\n",
    "\n",
    "    def activation(self, X):\n",
    "        \"\"\" Activate the logistic neuron\"\"\"\n",
    "        z = self.net_input(X)\n",
    "        return self._sigmoid(z)\n",
    "    \n",
    "    def predict_proba(self, X):\n",
    "        \"\"\"\n",
    "        Predict class probabilities for X.\n",
    "        \n",
    "        Parameters\n",
    "        ----------\n",
    "        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
    "            Training vectors, where n_samples is the number of samples and\n",
    "            n_features is the number of features.\n",
    "        \n",
    "        Returns\n",
    "        ----------\n",
    "          Class 1 probability : float\n",
    "        \n",
    "        \"\"\"\n",
    "        return activation(X)\n",
    "\n",
    "    def predict(self, X):\n",
    "        \"\"\"\n",
    "        Predict class labels for X.\n",
    "        \n",
    "        Parameters\n",
    "        ----------\n",
    "        X : {array-like, sparse matrix}, shape = [n_samples, n_features]\n",
    "            Training vectors, where n_samples is the number of samples and\n",
    "            n_features is the number of features.\n",
    "        \n",
    "        Returns\n",
    "        ----------\n",
    "        class : int\n",
    "            Predicted class label.\n",
    "        \n",
    "        \"\"\"\n",
    "        # equivalent to np.where(self.activation(X) >= 0.5, 1, 0)\n",
    "        return np.where(self.net_input(X) >= 0.0, 1, 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Reading-in the Iris data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>145</th>\n",
       "      <td>6.7</td>\n",
       "      <td>3.0</td>\n",
       "      <td>5.2</td>\n",
       "      <td>2.3</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>146</th>\n",
       "      <td>6.3</td>\n",
       "      <td>2.5</td>\n",
       "      <td>5.0</td>\n",
       "      <td>1.9</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>147</th>\n",
       "      <td>6.5</td>\n",
       "      <td>3.0</td>\n",
       "      <td>5.2</td>\n",
       "      <td>2.0</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>148</th>\n",
       "      <td>6.2</td>\n",
       "      <td>3.4</td>\n",
       "      <td>5.4</td>\n",
       "      <td>2.3</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149</th>\n",
       "      <td>5.9</td>\n",
       "      <td>3.0</td>\n",
       "      <td>5.1</td>\n",
       "      <td>1.8</td>\n",
       "      <td>Iris-virginica</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       0    1    2    3               4\n",
       "145  6.7  3.0  5.2  2.3  Iris-virginica\n",
       "146  6.3  2.5  5.0  1.9  Iris-virginica\n",
       "147  6.5  3.0  5.2  2.0  Iris-virginica\n",
       "148  6.2  3.4  5.4  2.3  Iris-virginica\n",
       "149  5.9  3.0  5.1  1.8  Iris-virginica"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import pandas as pd\n",
    "\n",
    "df = pd.read_csv('https://archive.ics.uci.edu/ml/'\n",
    "        'machine-learning-databases/iris/iris.data', header=None)\n",
    "df.tail()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "# select setosa and versicolor\n",
    "y = df.iloc[0:100, 4].values\n",
    "y = np.where(y == 'Iris-setosa', 1, 0)\n",
    "\n",
    "# extract sepal length and petal length\n",
    "X = df.iloc[0:100, [0, 2]].values\n",
    "\n",
    "# standardize features\n",
    "X_std = np.copy(X)\n",
    "X_std[:,0] = (X[:,0] - X[:,0].mean()) / X[:,0].std()\n",
    "X_std[:,1] = (X[:,1] - X[:,1].mean()) / X[:,1].std()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A function for plotting decision regions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from matplotlib.colors import ListedColormap\n",
    "\n",
    "def plot_decision_regions(X, y, classifier, resolution=0.02):\n",
    "\n",
    "    # setup marker generator and color map\n",
    "    markers = ('s', 'x', 'o', '^', 'v')\n",
    "    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')\n",
    "    cmap = ListedColormap(colors[:len(np.unique(y))])\n",
    "\n",
    "    # plot the decision surface\n",
    "    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1\n",
    "    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1\n",
    "    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),\n",
    "                         np.arange(x2_min, x2_max, resolution))\n",
    "    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)\n",
    "    Z = Z.reshape(xx1.shape)\n",
    "    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)\n",
    "    plt.xlim(xx1.min(), xx1.max())\n",
    "    plt.ylim(xx2.min(), xx2.max())\n",
    "\n",
    "    # plot class samples\n",
    "    for idx, cl in enumerate(np.unique(y)):\n",
    "        plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],\n",
    "                    alpha=0.8, c=cmap(idx),\n",
    "                    marker=markers[idx], label=cl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nvIZmXtw+bh+3TWOWvmqWkOr4RPyWN0jjc5enk4YoKz8db2ZmJVT4cJ+kn5FOMjlW0hOkD88NJZ0K\n5lLSObY+QjrA+iLppKVmZjYAFB5SEXHmVm7/NunccdYHbW1tRZfQ1Nw+XXP71Oa2aaymmN1XL+lE\n3eV5PGZmrU4SUeaJE2ZmNnA5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzM\nrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5\npMzMrGk5pMzMrGk5pMzMrGk5pMzMrGk5pMzMrGkVHlKSLpO0XNL9XWzzLUkLJM2RdEh/1mdmZsUp\nPKSAy4ETa90o6SRg74jYB/gQ8N3+KszMzIpVeEhFxG3Aqi42OQX4z2zb24FRksb3R21mZlaswkOq\nG3YDFueuL8nWmZlZybVCSJmZ2QA1pOgCumEJsEfu+u7ZuqpmzZr1yuW2tjba2toaVZeZmVVob2+n\nvb29bvtTRNRtZ70uQtoTuD4iDqxy28nAxyLijZKOAL4ZEUfU2E+89FIwbFhDyzUzs26SRESot79f\neE9K0s+ANmCspCeA84GhQETEpRHxG0knS3oEeAF4X1f7W7MGxo1rdNVmZtYfmqInVS+SYsGCYMqU\noisxMzPoe0+qdBMn1qwpugIzM6uX0oXUc88VXYGZmdVL6ULKPSkzs/IoXUi5J2VmVh6lCyn3pMzM\nyqN0IeWelJlZeZQupNyTMjMrj9KFlHtSZmblUbqQck/KzKw8ShdS7kmZmZVH6ULKPSkzs/IoXUi5\nJ2VmVh6lCyn3pMzMyqN0IeWelJlZeZQupJ5/Hkr07SNmZgNa6UJq2DB44YWiqzAzs3ooXUiNGuXj\nUmZmZVG6kBo50selzMzKonQh5Z6UmVl5lC6k3JMyMyuP0oWUe1JmZuVRupByT8rMrDxKF1LuSZmZ\nlUfpQso9KTOz8ig8pCTNkDRP0sOSzqpy+zGSVku6J1s+39X+3JMyMyuPIUXeuaRBwCXAccBS4E5J\n10bEvIpN/xARb+nOPt2TMjMrj6J7UtOBBRHxeESsB64ETqmynbq7Q/ekzMzKo+iQ2g1YnLv+ZLau\n0pGS5kj6taT9u9qhe1JmZuVR6HBfN90NTIyIdZJOAq4B9q218VVXzeLBB2HWLGhra6Otra2fyjQz\n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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1088a1b00>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "lr = LogisticRegression(n_iter=500, eta=0.2).fit(X_std, y)\n",
    "plt.plot(range(1, len(lr.cost_) + 1), np.log10(lr.cost_))\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Cost')\n",
    "plt.title('Logistic Regression - Learning rate 0.01')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\nIpmlJFVCy5Yt44tf/CI9evRg4MCB3HbbbZUOSUSkU+nUTdCz7swzz6Rbt2784x//YM6cORx55JHs\ntdde7LLLLpUOTUSkU6jZJHXosGHUJ34IXNevH3978smi7X/VqlVMnTqVF154ge7duzN8+HCOOeYY\nbrrpJi6//PKiHUdEpJpVZZJqnoCgZRKqX7qUp7bYYv38vs2272gSW7hwIRtuuCE77bTT+mV77rkn\nM2fOTL0PEZFaV5VJqnkCgpZJqK37aOvzV65cSV1dXZNldXV1rFixok37ERGpZWo4USI9evSgvr6+\nybLly5fTs2fPCkUkItL5VGVJKo26fv2alI7q+vUr6v4HDRrEmjVrWLx48foqv3nz5jFkyJCiHkdE\npJpVZZJqnoAaliUVs5FELptssgnHHXccl1xyCddddx1z5sxh2rRpPProoyU9rohINanKJFWMBFSM\nktbVV1/NaaedRr9+/dh888255ppr1PxcRKQNKpqkzGxbYAqwJbAOuM7df1nJmBoUI9H16dOHu+66\nqwjRiIjUpkqXpNYA57n7XDPrATxtZg+4+0sVjktERDKgoq373P0dd58bp1cCLwL9KxmTiIhkR2aa\noJvZDsBewOOVjURERLKi0tV9AMSqvj8C58QSVQvjp01bPz1y0CBGDh5cpuhERKTYZixYwIyFC1vd\nruJJysy6EhLUTe5+T77txo8aVb6gRESkpEYOHtyksDFh+vSc22Whuu+3wAvu/otKByIiItlS0SRl\nZsOB0cChZvaMmc0xs8MqGZOIiGRHRav73H02sEElYxARkezKQnWfiIhITkpSJXT11VczbNgwunXr\nxmmnnVbpcEREOp2aTFJz5kCy/9m//Q0+/rj4x+nfvz8XX3wxp59+evF3LiJSA6ouSbnD7NnhL8Cq\nVSEpJb34IowZExLVlClw1VXQfCzChufnm0/j2GOP5eijj6Zv375tf7KIiFT+d1LFtmoV/PKXMH8+\nnHwynH027LwzDB3auM3o0bB2LRxxBHTrBlOnwmabNa5fuBB+9Su48kro3h2uvx423hi+9rXyn4+I\nSC2rupLUppvCb34Df/4zjBgBO+wA55/ftn184hPQty+ce25IVvffHxKaiIiUV9WVpCCUjjbcMEz3\n7QtmTdffcgvcdVdIZPffH6r+rr++sTTVpQtccgnstx889RTcc0/TkpaIiJRH1ZWk/v3vUMW3997w\n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\nPbz9dphftiwsay7NfZG01VfF3Fea6qsePUL3RlvHO599+uRuOJHmmMWsLkt7r8lyfOXKtUxEWleo\nx4mvA6cA+wJPJVbVAzdq0MPKKWaT6rTK3Qw6q82u08aV1fhFsmrMmNxN0Av1OHEjcKOZHe/ud5Y0\nOpEEdRzbNuotQ6pZmt9JzTazyWZ2H4CZ7WpmHfohr7Rf8j7M6NFh+oknWm6XvBdz0klhOvnbnbYo\n5r7SaOg49jOfCY/bbw/LKi3tdSj39WqohnzttfC4886wTKQapOlx4j7gBkKz8T3NrCvwjLvvXo4A\nYwyq7osq0Rddub+pl7vj2LbEleY6VKJko+pF6ezaXN2XsLm7/8HMxgK4+xozW1v0CCXVh1vaZtDF\nbLpc7mbQdXWw1VaN81ttVfkEBemvg5qNixRPmuq+f5nZZoQf4WJmBwDLCz9F2kPVNkG5q8s6O10v\nqWZpqvuGEpqK7wY8B2wBfMndny19eOtjqJnqPlXbqCFAW+l6STVod3Wfu88xs4OBwYTfSi1w99Ul\niFHKLKsfbqouaxtdL6lmrVb3mVk34GzgMmAC8O24TIpMrcJERJpKU933B2AFECuhOBHo7e5fLnFs\nyRhqorpPrcJEpFZ1pHXfbu6e7HXsYTN7oXihSQNV24iINJWmdd+c2KIPADPbn6bdJEknpVZhIpJ1\naUpS+wCPmlnDx9f2wAIzmw+4u+9RsuikpDRWkYhkXZokdVjJo5CKUPWiiGRdmibor5UjEBERkebS\n3JMSERGpCCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUp\nERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJ\nLCUpERHJLCUpERHJLCUpERHJLCUpERHJLCUpERHJrIolKTP7kZm9aGZzzexOM6urVCwiIpJNlSxJ\nPQAMcfe9gEXA2ArGIiIiGVSxJOXuf3X3dXH2MWDbSsUiIiLZlJV7UqcB91U6CBERyZaupdy5mT0I\nbJlcBDhwkbtPi9tcBKx291sL7WvatPHrpwcNGsngwSOLHa6IiJTJggUzWLhwRqvbmbuXPpp8Bzc7\nBfgmcKi7f1RgO580qXJxiohIaY0ZY7i7NV9e0pJUIWZ2GHA+MKJQghIRkdpVyXtSVwE9gAfNbI6Z\n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\nAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x107f1add8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_decision_regions(X_std, y, classifier=lr)\n",
    "plt.title('Logistic Regression - Gradient Descent')\n",
    "plt.xlabel('sepal length [standardized]')\n",
    "plt.ylabel('petal length [standardized]')\n",
    "plt.legend(loc='upper left')\n",
    "plt.tight_layout()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
